package com.ezandroid.library.network.http.request;

import java.io.IOException;
import java.util.Map;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request.Builder;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * A {@link HttpStack} based on {@link OkHttpClient}.
 *
 * @author markmjw
 * @date 2015-05-29
 */
public class HttpStackImpl implements HttpStack {

    private final OkHttpClient mClient;

    public HttpStackImpl() {
        this(new OkHttpClient.Builder().build());
    }

    public HttpStackImpl(OkHttpClient client) {
        if (null == client) {
            throw new IllegalArgumentException("The parameter client can't be null.");
        }
        mClient = client;
    }

    @Override
    public Response performRequest(Request<?> request) throws IOException {
        // 设置url
        Builder builder = new Builder();
        builder.url(request.getUrl());

        // 设置header
        Map<String, String> map = request.getHeaders();
        for (String headerName : map.keySet()) {
            builder.header(headerName, map.get(headerName));
        }

        // 设置parameter
        covertParameters(builder, request);

        // 执行请求
        Response response = mClient.newCall(builder.build()).execute();

        int responseCode = response.code();
        if (responseCode == -1) {
            throw new IOException("Could not retrieve response code from OkHttpClient.");
        }
        return response;
    }

    private void covertParameters(Builder builder, Request<?> request) throws IOException {
        switch (request.getMethod()) {
            case Request.Method.GET:
                builder.get();
                break;
            case Request.Method.DELETE:
                builder.delete();
                break;
            case Request.Method.POST:
                builder.post(covertBody(request));
                break;
            case Request.Method.PUT:
                builder.put(covertBody(request));
                break;
            case Request.Method.HEAD:
                builder.head();
                break;
            case Request.Method.PATCH:
                builder.patch(covertBody(request));
                break;
            default:
                throw new IllegalStateException("Unknown method type.");
        }
    }

    private RequestBody covertBody(Request<?> request) throws IOException {
        byte[] body = request.getBody();
        if (null != body) {
            return RequestBody.create(MediaType.parse(request.getBodyContentType()), body);
        } else {
            return null;
        }
    }
}
